Proximity
SQL Server 2008 FTS
supports the proximity predicate, which allows you to search on tokens
that are close, or near, to each other. Near is defined as within 50 words. Words separated by more than 50 words do not show up in a CONTAINS or CONTAINSTABLE search. With a FREETEXT or FREETEXT table search, the separation distance can be up to 1,326 words. Here is an example of a proximity-based search:
SELECT * FROM Person.Contact WHERE CONTAINS(*, '"peanut butter" NEAR "jam"')
Weighted
A weighted search allows you to assign different weights to search tokens; you use the ISABOUT predicate to do a weighted search. If you want to search on Gulf of Mexico and Oil, and you want to place more emphasis on Gulf of Mexico than on Oil, you could query like this:
SELECT * FROM Person.Contact
WHERE CONTAINS(*, 'isabout("Gulf of Mexico" weight(0.7), Oil weight(0.1))')
You can use multiple weighted search items in a search, but doing so decreases the search speed.
LANGUAGE
Sometimes you might want to
conduct a search in a different language than the default full-text
language for your server. For example, say you want to conduct a
German-language search on the contents of a column. To do this, you
would use the language predicate like this:
SELECT * FROM Person.Contact WHERE CONTAINS(*, 'volkswagen', LANGUAGE 1031)
In this search, German language rules are applied when searching the index. In this case, the search on Volkswagen is expanded to a search on Volkswagen, wagen, and volk.
If you are storing multilingual content in a single column, you should
have a column that indicates the language of the content stored in the
column. Otherwise, your searches might return unwanted results from
content in different languages.
CONTAINSTABLE
CONTAINSTABLE supports all the predicates of the CONTAINS operator but returns a result set containing only the key and rank. The CONTAINSTABLECONTAINS, but it allows you to use the TOP_n_BY RANK parameter to return only the first n results. Because the CONTAINSTABLE
predicate returns only the key value and rank, you have to join it
against the base table (or another related table) to get meaningful
results. Here are some examples: clause also supports all predicates of
SELECT * FROM Person.Contact JOIN
(SELECT [key], rank FROM CONTAINSTABLE(Person.Contact, *, 'test')) AS k
ON k.[key]= Person.Contact.ContactID
In the following example, Person.Contact is a child table of the Sales.Individual table. Sales.Individual has a foreign key relationship to the Person.Contact table’s primary key, ContactID. This query illustrates how you could join the CONTAINSTABLE result set from the Person.Contact table against the Sales.Individual table (this example also illustrates the TOP_n_BY_RANK option):
SELECT * FROM Sales.Individual as s
JOIN (SELECT [key], rank FROM CONTAINSTABLE(Person.Contact, *, 'jon',100)) AS k
ON k.[key]=s.Contactid order by rank desc
In this query, you limit the
results to the top 100 rows. The second query returns, at most, 100 rows
with the highest-rank values.
Keep in mind that CONTAINS is faster than FREETEXT, but it is a strict character-by-character match, unless you use some of the word-generation searches.
FREETEXT and FREETEXTTABLE
FREETEXT and FREETEXTTABLE incorporate what Microsoft considers to be the natural way to search. For example, if you were searching on book, you would expect to get hits to rows containing the word books (the plural). If you were searching on the word swimming, you would expect results containing the words swimming, swim, swims, swum, and so on. The FreeText and FREETEXTTABLE
queries implicitly search on all generations of a word and include a
proximity-based search. However, if you wrap your search in double
quotation marks, the FREETEXT and FREETEXTTABLE predicates do not do any stemming. FREETEXT and FREETEXTTABLE also include the TOP_n_BY_RANK parameter.
Here are some examples using FREETEXT and FREETEXTTABLE:
Use AdventureWorks;SELECT * from Person.Contact where Freetext(*,'Barack Obama')
Corrected! HPC
Use AdventureWorks;
SELECT * FROM Sales.Individual as s
JOIN (SELECT [key], rank FROM FREETEXTTABLE(Person.Contact, *, 'jon',100)) AS k
ON k.[key]=s.Contactid order by rank desc
Notice that the FREETEXTTABLE example does the functional equivalent of a CONTAINSTABLE query because the search is wrapped in double quotation marks.